//========================================================================
// *作者：海盗猫  主页：ilplay.com
// *脚本：HDMPackageHotfix
// *描述：
// *?2021 MYJL . All rights reserved.
//* ======================================================================
using HybridCLR;
using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using UnityEngine;

namespace HDMCode.Hotfix
{
    public abstract class HDMPackageHotfix : HDMPackageHotfixBase
    {
        /// <summary>
        /// 指定热更的资源包名
        /// </summary>
        [Header("资源包名")]
        public string assetspackageName = "";
        /// <summary>
        /// 指定热更的补丁包名
        /// </summary>
        [Header("补丁包名")]
        public string scriptPackageName = "";

        /// <summary>
        /// 用于补充的元数据
        /// </summary>
        [Header("元数据")] [SerializeField] public List<string> mateDate = default;

        /// <summary>
        /// 用于补充的元数据
        /// </summary>
        [Header("热数据")] [SerializeField] public List<string> hotfoxDate = default;

        /// <summary>
        /// 资源下载地址
        /// </summary>
        [Header("资源地址")]
        public AssetsAddress DowanerAdderss;

        /// <summary>
        /// 当前资源包
        /// </summary>
        protected YooAsset.ResourcePackage AssetsPackage { get; set; }

        /// <summary>
        /// 当前补丁包
        /// </summary>
        protected YooAsset.ResourcePackage ScriptPackage { get; set; }

        /// <summary>
        /// 用于最先的初始化方法
        /// </summary>
        protected abstract void AssetsInit();

        /// <summary>
        /// 检测到不需要更新时
        /// </summary>
        protected abstract void NotUpdated();

        /// <summary>
        /// 检测到需要更新时
        /// </summary>
        /// <param name="fileCount">需要更新的文件数量</param>
        /// <param name="fileByteSize">需要更新的文件总大小</param>
        /// <returns>返回是否立即更新</returns>
        protected abstract void NeedUpdated(AssetsDownloadInfo[] downloadInfo);

        /// <summary>
        /// 开始下载时
        /// </summary>
        /// <param name="fileName">下载的文件名称</param>
        /// <param name="sizeBytes">下载的文件大小</param>
        protected abstract void DownloadStart(string fileName, long sizeBytes);

        /// <summary>
        /// 下载主资源进度回调
        /// </summary>
        /// <param name="totalDownloadCount">总下载数量</param>
        /// <param name="currentDownloadCount">当前下载数量</param>
        /// <param name="totalDownloadBytes">总下载大小</param>
        /// <param name="currentDownloadBytes">当前下载大小</param>
        protected abstract void DownloadMainProgress(int totalDownloadCount, int currentDownloadCount, long totalDownloadBytes, long currentDownloadBytes);
        /// <summary>
        /// 下载次资源进度回调
        /// </summary>
        /// <param name="totalDownloadCount">总下载数量</param>
        /// <param name="currentDownloadCount">当前下载数量</param>
        /// <param name="totalDownloadBytes">总下载大小</param>
        /// <param name="currentDownloadBytes">当前下载大小</param>
        protected virtual void DownloadSubProgress(int totalDownloadCount, int currentDownloadCount, long totalDownloadBytes, long currentDownloadBytes) { }

        /// <summary>
        /// 下载成功时
        /// </summary>
        /// <param name="packName">成功的包名</param>
        protected abstract void DownloaderSucceed(string packName);

        /// <summary>
        /// 下载结束时,无论成功或失败
        /// </summary>
        /// <param name="totalDownloadCount">下载的文件总数量</param>
        protected abstract void DownloadOver(bool totalDownloadCount);

        /// <summary>
        /// 检测校验异常时
        /// </summary>
        /// <param name="errorInfo"></param>
        protected abstract void VerifyError(string errorInfo);

        /// <summary>
        /// 下载异常时
        /// </summary>
        /// <param name="fileName">文件名称</param>
        /// <param name="error">错误信息</param>
        protected abstract void DownloadError(string fileName, string error);

        /// <summary>
        /// 初始化下载
        /// </summary>
        private void Awake()=> CheckAssetsUpdate();


        public void PlatformAddress()
        {
#if (UNITY_EDITOR)
            defaultHostServer = DowanerAdderss.TestDefaultHostServer;
            fallbackHostServer = DowanerAdderss.TestFallbackHostServer;
#elif(UNITY_ANDROID)
            defaultHostServer = DowanerAdderss.AndroidDefaultHostServer;
            fallbackHostServer = DowanerAdderss.AndroidFallbackHostServer;
#elif(UNITY_IOS)
            defaultHostServer = DowanerAdderss.IOSDefaultHostServer;
            fallbackHostServer = DowanerAdderss.IOSFallbackHostServer;
#endif
        }

        /// <summary>
        /// 检查单个资源包
        /// </summary>
        /// <returns></returns>
        public void CheckAssetsUpdate()
        {
            DontDestroyOnLoad(this.gameObject);
            PlatformAddress();
            AssetsInit();
            switch (PlayMode)
            {
                case YooAsset.EPlayMode.EditorSimulateMode:

                    StartCoroutine(EditorInitializePackage(assetspackageName, scriptPackageName, SimulationCheckUpdate));
                    break;
                case YooAsset.EPlayMode.OfflinePlayMode:
                    StartCoroutine(OfflineInitializePackage(scriptPackageName, VerifyError, RealCheckUpdate, RealChenckUnUpdate));
                    break;
                case YooAsset.EPlayMode.HostPlayMode:
                    StartCoroutine(InitializePackage(scriptPackageName, VerifyError, RealCheckUpdate, RealChenckUnUpdate));
                    break;
            }
        }

        /// <summary>
        /// 模拟检测更新
        /// </summary>
        /// <param name="mainPackage"></param>
        /// <param name="subPackage"></param>
        public void SimulationCheckUpdate(YooAsset.ResourcePackage mainPackage, YooAsset.ResourcePackage subPackage) 
        {
            ScriptPackage = subPackage;
            AssetsPackage = mainPackage;
            HDMAssetsLoad.scriptPackagee = ScriptPackage;
            HDMAssetsLoad.assetsPackage = AssetsPackage;
            NotUpdated();
        }

        /// <summary>
        /// 实机检测需要更新
        /// </summary>
        /// <param name="downloadInfo"></param>
        public void RealCheckUpdate(AssetsDownloadInfo downloadInfo) 
        {
            ScriptPackage = downloadInfo.package;
            StartCoroutine(InitializePackage(assetspackageName, VerifyError, 
                (result)=> 
                { 
                    NeedUpdated(new AssetsDownloadInfo[] { downloadInfo, result }); 
                    AssetsPackage = result.package; 
                } ,
                (resultInsid) => 
                {  
                    AssetsPackage = resultInsid.package;
                    HDMAssetsLoad.scriptPackagee = ScriptPackage;
                    HDMAssetsLoad.assetsPackage = AssetsPackage;
                    NeedUpdated(new AssetsDownloadInfo[] { downloadInfo}); } 
                ));
        }

        /// <summary>
        /// 实机检测无需更新
        /// </summary>
        /// <param name="downloadInfo"></param>
        public void RealChenckUnUpdate(AssetsDownloadInfo downloadInfo)
        {
            ScriptPackage = downloadInfo.package;
            StartCoroutine(InitializePackage(assetspackageName, VerifyError, 
                (result) => 
                { 
                    NeedUpdated(new AssetsDownloadInfo[] { result }); 
                    AssetsPackage = result.package; 
                },
                (resultInsid) => {  
                    AssetsPackage = resultInsid.package;
                    HDMAssetsLoad.scriptPackagee = ScriptPackage;
                    HDMAssetsLoad.assetsPackage = AssetsPackage;
                    NotUpdated(); 
                }));
        }

        /// <summary>
        /// 下载单个资源包
        /// </summary>
        /// <param name="packageName">需要下载的资源包</param>
        public void PackageDownload(string packageName) 
        {
            StartCoroutine(RunAssetsDownload(packageName, DownloadError, DownloadMainProgress, DownloadOver, DownloadStart,
                (result)=> 
            {
                HDMAssetsLoad.scriptPackagee = ScriptPackage;
                HDMAssetsLoad.assetsPackage = AssetsPackage;
                DownloaderSucceed(result); 
            }));
        }

        /// <summary>
        /// 下载合并资源包
        /// </summary>
        /// <param name="mainPackageName">资源包名字</param>
        /// <param name="subPackageName">补丁包名称</param>
        public void PackageDownload(string mainPackageName, string subPackageName)
        {
            StartCoroutine(RunAssetsDownloads(mainPackageName, subPackageName, DownloadError, DownloadMainProgress, DownloadSubProgress, DownloadOver, DownloadStart, 
                (result) =>
            {
                HDMAssetsLoad.scriptPackagee = ScriptPackage;
                HDMAssetsLoad.assetsPackage = AssetsPackage;
                DownloaderSucceed(result);
            }));
        }

        /// <summary>
        /// 添加元数据到内存
        /// </summary>
        public void AddMateDateToRAM(Action action) 
        {
            HDMAssetsLoad.scriptPackagee = ScriptPackage;
            StartCoroutine(LoadMateDate(hotfoxDate, mateDate,action));
        }
    }
}


